1. /* sdfagmpi.cpp by K.Tsuru */
  2. // function ID 3552 DRADIX only
  3. #ifndef SN_H
  4. #include "sn.h"
  5. #endif
  6. /*******************************************************
  7. It Provides pi by Arithmetic and Geometric mean method
  8. ********************************************************/
  9. static SDouble Sqrt2(const SDouble& a, const SDouble& b){
  10. RealSize C;
  11. uint sz = a.MaxSize();
  12. SDouble w(a.Type(), sz), y(a.Type(), sz), one(1.0);
  13. static SDouble recsqrt(0.0);
  14. uint ef = (DOUBLE_FIG*2u)/DFIGURES, fig = a.EffFig();
  15. int c = DDCompare(a, b);
  16. if(!c) return a; // a == b
  17. long agfig = AgreeUpTo(a, b);
  18. w = a*b;
  19. if(agfig < (long)ef*DFIGURES) return Sqrt(w);
  20. ef = (uint)max((long)ef, (2*agfig)/DFIGURES);
  21. ef = min(ef, fig);
  22. int power = w.RdxExp()*DFIGURES/2;
  23. w.MultPowRdx( -w.RdxExp() );
  24. /* set an initial value y0 */
  25. if( w < 0.01 ) { w *= 100.0; power--; }
  26. C.SetEffFig(ef);
  27. if(recsqrt.Sign()){
  28. y = recsqrt;
  29. }else {
  30. double w0=doubleD(w);
  31. y = 1./sqrt(w0);
  32. }
  33. C.SetEffFig(0);
  34. SDouble delta(a.Type(), sz);
  35. w.FixedPoint(w.RdxExp());
  36. int fp = 0, itrmax = howpow2( (DFIGURES*y.MaxSize())/DOUBLE_FIG+1 ) +6;
  37. c = 0;
  38. do{
  39. if( (ef = C.SetEffFig(ef) ) >= fig) fp = 1;
  40. delta = one-w*(y*y);
  41. delta *= y;
  42. delta /= 2;
  43. y += delta;
  44. c++;
  45. ef *= 2;
  46. if(ef > fig) ef = fig;
  47. C.SetEffFig(0);
  48. } while( (!delta.IsMLT(y) && (c < itrmax)) || !fp );
  49. recsqrt = y;
  50. y.MultPow10(-power);
  51. y = w*y;
  52. #ifndef NDEBUG
  53. if(c == itrmax) y.SetError(y.FATAL, "Sqrt2()", 3552);
  54. #endif
  55. // y.iterationCount = c;
  56. y.PointFree();
  57. y.Reform(10011);
  58. return y;
  59. }
  60. /// Using Gauss-Legendre method ///
  61. SDouble AGMPi(){
  62. SDouble a(1.0), b(2.0), t(0.25), x(1.0), y, d, pi;
  63. int c;
  64. b = RecSqrt(b);
  65. y.FixedPoint(0);
  66. int itrmax = 2*howpow2(a.MaxSize());
  67. c = 0;
  68. do{
  69. y = a;
  70. a = (a+b)/2.0;
  71. b = Sqrt2(b, y);
  72. // fprintf(stderr, "Iteration counts = %2d\n", b.ItrCounts());
  73. d = y-a;
  74. d *= d;
  75. t = t - x*d;
  76. x *= 2;
  77. d = a - b;
  78. c++;
  79. } while(!d.IsMLT(a) && (c < itrmax) );
  80. #ifndef NDEBUG
  81. if(c == itrmax) y.SetError(y.FATAL, "AGMPi()", 3552);
  82. #endif
  83. d = a+b;
  84. d *= d; t *= 4;
  85. pi = d/t;
  86. pi.iterationCount = c;
  87. return pi;
  88. }

sdfagmpi.cpp : last modifiled at 2016/09/04 14:21:40(2,214 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).